package com.ruoyi.consumer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.impl.AMQImpl;
import com.ruoyi.entity.DriverLocation;
import com.ruoyi.entity.Order;
import com.ruoyi.websocket.OrderChanel;
import com.ruoyi.websocket.SpringContextUtil;
import io.lettuce.core.api.async.RedisGeoAsyncCommands;
import io.micrometer.core.instrument.Meter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import springfox.documentation.spring.web.json.Json;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author : Xuzhaobo
 * @date : 2024-12-25 13:49
 * @description :
 **/
@Component
@RabbitListener(queues = "taxi-delay-queue")
@Slf4j
public class OrderConsumer {


    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @RabbitHandler
    public void consumer(String id, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) Long tag) throws IOException {

        log.info("第一轮中签id:"+id);
        List<String> drivers = redisTemplate.opsForList().range("takeOrder:" + id, 0, -1);

        String json = redisTemplate.opsForValue().get("order:" + id);
        Order order = JSON.parseObject(json, Order.class);
        if (drivers.isEmpty()){
            Point point = new Point(Double.parseDouble(order.getStartLongitude()), Double.parseDouble(order.getEndLongitude()));
            Circle circle = new Circle(point, new Distance(4, Metrics.KILOMETERS));
            RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs
                    .newGeoRadiusArgs()
                    .includeDistance()
                    .includeCoordinates()
                    .sortAscending();

            GeoResults<RedisGeoCommands.GeoLocation<String>> radius = redisTemplate.opsForGeo().radius("beijing-driver-geo", circle, args);

            List<GeoResult<RedisGeoCommands.GeoLocation<String>>> list = radius.getContent();
            ArrayList<DriverLocation> driverList = new ArrayList<>();

            if (list.size()>0){
                for (GeoResult<RedisGeoCommands.GeoLocation<String>> obj : list) {
                    RedisGeoCommands.GeoLocation<String> content = obj.getContent();
                    String name = content.getName();
                    Point point1 = content.getPoint();
                    double x = point1.getX();
                    double y = point1.getY();
                    DriverLocation driverLocation = new DriverLocation();
                    driverLocation.setCarCode(name);
                    driverLocation.setLongitude(String.valueOf(x));
                    driverLocation.setLatitude(String.valueOf(y));
                    driverList.add(driverLocation);

                }
            }
            for (DriverLocation driverLocation : driverList) {
                String carCode = driverLocation.getCarCode();
                OrderChanel.sendMessage(carCode, JSONObject.toJSONString(order));
            }
            rabbitTemplate.convertAndSend("taxi-order-delayEx2", "", id, new MessagePostProcessor() {
                @Override
                public Message postProcessMessage(Message message) throws AmqpException {
                    message.getMessageProperties().setDelay(30*1000);

                    return message;
                }
            });




        }else if (drivers.size()==1){

            String carCode = drivers.get(0);
            OrderChanel.sendMessage(carCode,"恭喜中签");

        }else {

            String driver=null;
            double score=0;

            Point point = new Point(Double.parseDouble(order.getStartLongitude()), Double.parseDouble(order.getEndLongitude()));
            StringRedisTemplate stringRedisTemplate = SpringContextUtil.getBean(StringRedisTemplate.class);
            stringRedisTemplate.opsForGeo().add("beijing-order-driver-geo:"+id,point,"起点");

            for (String carCode : drivers) {

                Integer realScore = (Integer) stringRedisTemplate.opsForHash().get("driver:" + carCode, "score");

                if (realScore==null){
                    realScore=100;
                }

                List<Point> position = stringRedisTemplate.opsForGeo().position("beijing-driver-geo", carCode);
                stringRedisTemplate.opsForGeo().add("beijing-order-driver-geo:"+id,position.get(0),carCode);
                Distance distance = stringRedisTemplate.opsForGeo().distance("beijing-order-driver-geo:" + id, "起点", carCode);
                double distanceValue = distance.getValue();

                String unit = distance.getUnit();
                System.out.println(distanceValue+"--"+unit);
                double finalScore=realScore-distanceValue/100;
                log.info("司机：{},得分：{}", carCode, finalScore);

                if (finalScore>score){
                    driver=carCode;
                    score=finalScore;
                }

            }
            OrderChanel.sendMessage(driver,"恭喜中签");



        }
        channel.basicAck(tag,true);




    }




}
